package com.ms.jsf;

import com.ms.exception.DpwcException;
import com.ms.exception.DpwcSpringValidationException;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.validation.MapBindingResult;
import org.springframework.validation.ObjectError;

import java.text.MessageFormat;
import java.util.*;

/**
 * User: gmc
 * Date: 06/04/13
 */
@Component
public class ErrorMessageResolver {

    ResourceBundle errorResourceBundle;

    public String getErrorMessage(DpwcException dpwcException, ResourceBundle errorResourceBundle) {
        this.errorResourceBundle = errorResourceBundle;
        if (!(dpwcException instanceof DpwcSpringValidationException)) {
            return getErrorMessage(dpwcException.getMessage(), dpwcException.getParameters());
        }
        DpwcSpringValidationException springValidationException = (DpwcSpringValidationException) dpwcException;
        if (!springValidationException.isSpringValidation()) {
            return getErrorMessage(dpwcException.getMessage(), dpwcException.getParameters());
        }
        return getErrorMsgFrom(springValidationException);
    }

    private String getErrorMsgFrom(DpwcSpringValidationException springValidationException) {
        String mainMessage = springValidationException.getMainMessage();
        Object[] parameters = springValidationException.getParameters();
        MapBindingResult errors = springValidationException.getSpringValidationErrors();
        boolean isJsr303 = springValidationException.isJsr303();
        StringBuilder stringBuilder = new StringBuilder();
        for (ObjectError objectError : errors.getAllErrors()) {
            if (isJsr303) {
                stringBuilder.append(getErrorMessage(objectError));
            } else {
                String errorCode = objectError.getCode();
                stringBuilder.append(getErrorMessage(errorCode, objectError.getArguments()));
            }
            stringBuilder.append("<br />");
        }
        String detailErrorMsg = stringBuilder.toString();
        String fullErrorMsg = detailErrorMsg;
        if (StringUtils.hasText(mainMessage)) {
            List allParameters = new ArrayList();
            if (parameters != null && parameters.length > 0) {
                allParameters.addAll(Arrays.asList(parameters));
            }
            allParameters.add(detailErrorMsg);
            fullErrorMsg = getErrorMessage(mainMessage, allParameters.toArray());
        }
        return fullErrorMsg;
    }

    private Object getErrorMessage(ObjectError objectError) {
        String[] codes = objectError.getCodes();
        for (String code : codes) {
            if (errorResourceBundle.containsKey(code)) {
                String errorMessage = getErrorMessage(code, objectError.getArguments());
                return errorMessage;
            }
        }
        return getErrorMessage(objectError.getDefaultMessage(), null);
    }

    public String getErrorMessage(String key, Object[] parameters) {
        // If the key is the real message it will have at leas one space
        if (key.contains(" ")) {
            return key;
        }
//        FacesContext facesContext = FacesContext.getCurrentInstance();
//        final UIViewRoot viewRoot = facesContext.getViewRoot();
//        String text = errorMsgSource.getMessage(key, parameters, viewRoot.getLocale());
        String text = null;
        try {
            text = errorResourceBundle.getString(key);
        } catch (MissingResourceException e) {
            text = key;
        }
        if (parameters != null && parameters.length > 0) {
            MessageFormat messageFormat = new MessageFormat(text);
            text = messageFormat.format(parameters);
        }
        return text;
    }

}
